#include "xmlfuncblock.h"

#include <QDomDocument>
#include <QDebug>
#include <QFile>

XmlFuncBlock::XmlFuncBlock(SchematicBase *parent, QString xml_filename)
    : FuncBlockBase(parent)
{
    qDebug() << "xml_filename=" << xml_filename;

    QFile xmlFile(xml_filename);
    QDomDocument doc;
    int errorLine, errorColumn;
    QString errorMsg;
    if (!doc.setContent(&xmlFile, &errorMsg, &errorLine, &errorColumn))
    {
            QString error("Syntax error line %1, column %2:\n%3");
            error = error
                    .arg(errorLine)
                    .arg(errorColumn)
                    .arg(errorMsg);
            qDebug() << error;
            return;
    }

    QDomNode rootNode = doc.firstChild();		
    while (!rootNode.isNull())
	{
		QDomElement root = rootNode.toElement();
		if (root.tagName() == "Component")
			break;
		rootNode = rootNode.nextSibling();
	}
	if (rootNode.isNull())
		return;

	QDomElement root = rootNode.toElement();
    qDebug() << "root=" << root.tagName();
	if (root.tagName() == "Component")
    {
        QDomNode node = root.firstChild();
        QDomElement nodeElement;

        while(!node.isNull())
        {
            nodeElement = node.toElement();
            qDebug() << nodeElement.tagName();
            if (nodeElement.tagName() == "Line")
            {
                bool ok;
                int x1=0, x2=0, y1=0, y2=0;
                if (nodeElement.hasAttribute("x1"))
                    x1 = nodeElement.attribute("x1", "0").toInt(&ok, 10);
                if (nodeElement.hasAttribute("x2"))
                    x2 = nodeElement.attribute("x2", "0").toInt(&ok, 10);
                if (nodeElement.hasAttribute("y1"))
                    y1 = nodeElement.attribute("y1", "0").toInt(&ok, 10);
                if (nodeElement.hasAttribute("y2"))
                    y2 = nodeElement.attribute("y2", "0").toInt(&ok, 10);

                qDebug() << "append QLine " << x1 << " " << y1 << " " << x2 << " " << y2;
                this->vimage->append(new QLine(x1, y1, x2, y2));
            }
            if (nodeElement.tagName() == "Pin")
            {
                bool ok;
                int x=0, y=0;
                unsigned int id=0, no=0;
                unsigned char datawidth=1;
                QString name = "", direction = "";
                enum pinDirection_t dir;

                if (nodeElement.hasAttribute("x"))
                    x = nodeElement.attribute("x", "0").toInt(&ok, 10);
                if (nodeElement.hasAttribute("y"))
                    y = nodeElement.attribute("y", "0").toInt(&ok, 10);
                if (nodeElement.hasAttribute("name"))
                    name = nodeElement.attribute("name");
                if (nodeElement.hasAttribute("no"))
                    no = nodeElement.attribute("no").toInt(&ok, 10);
                if (nodeElement.hasAttribute("datawidth"))
                    datawidth = nodeElement.attribute("datawidth").toInt(&ok, 10);
                if (nodeElement.hasAttribute("type"))
                    direction = nodeElement.attribute("type");
                direction.toLower();
                if (direction == "input")
                    dir = dirInput;
                else if (direction == "output")
                    dir = dirOutput;
                else
                    dir = dirUnknown;

                qDebug() << "append QPoint " << x << " " << y;
                if (getPinRefByNo(no) == NULL)
                    this->vpins->append(new PinFB(this, x, y, schematicParent->getNewConnectID(), datawidth, x, y, name, no, dir));
                else
                {
                    throw XmlFuncBlockException();//.setMessage("Pin with number " + QString().setNum(no) + " already exists" + endl);
                }
            }
            if (nodeElement.tagName() == "Text")
            {
                bool ok;
                int x=0, y=0;
                QString text="";

                if (nodeElement.hasAttribute("x"))
                    x = nodeElement.attribute("x", "0").toInt(&ok, 10);
                if (nodeElement.hasAttribute("y"))
                    y = nodeElement.attribute("y", "0").toInt(&ok, 10);
                if (nodeElement.hasAttribute("text"))
                    text = nodeElement.attribute("text");
                qDebug() << "append TextBase " << x << " " << y << text;
                this->texts->append(new TextBase(x, y, text));
            }
            else if (nodeElement.tagName() == "Size")
            {
                bool ok;
                int w=0, h=0;

                if (nodeElement.hasAttribute("width"))
                    w = nodeElement.attribute("width", "0").toInt(&ok, 10);
                if (nodeElement.hasAttribute("height"))
                    h = nodeElement.attribute("height", "0").toInt(&ok, 10);

                qDebug() << "Size " << w << " " << h;
                this->setGeometry(1, 1, w, h);
            }
            else if (nodeElement.tagName() == "Params")
            {
                QDomNode childNode = node.firstChild();
                while (!childNode.isNull())
                {
                    QDomElement child = childNode.toElement();
                    if (child.tagName() == "Param")
                    {
                        ParamBase *p = new ParamBase();
                        QString name = "";
                        QString datatype = "";
                        int min = 0, max = 0;
                        unsigned int paramid = 0;
                        QString value = "";
                        bool ok;
                        enum paramDataType_t pdt = pdtUByte;

                        if (child.hasAttribute("name"))
                            name = child.attribute("name", "0");
                        if (child.hasAttribute("datatype"))
                            datatype = child.attribute("datatype", "0");
                        if (child.hasAttribute("value"))
                            min = child.attribute("min", "0").toInt(&ok, 10);
                        if (child.hasAttribute("value"))
                            value = child.attribute("value", "0");
                        if (child.hasAttribute("paramid"))
                            paramid = child.attribute("paramid", "0").toInt(&ok, 10);
                        if (datatype == "ubyte")
                            pdt = pdtUByte;
                        else if (datatype == "sbyte")
                            pdt = pdtSByte;
                        else if (datatype == "uint")
                            pdt = pdtUInt;
                        else if (datatype == "sint")
                            pdt = pdtSInt;
                        else if (datatype == "ulong")
                            pdt = pdtULong;
                        else if (datatype == "slong")
                            pdt = pdtSLong;
                        else if (datatype == "caption")
                            pdt = pdtCaption;
                        p->datatype = pdt;
                        p->min = min;
                        p->max = max;
                        p->name = name;
                        p->value = value;
                        p->paramid = paramid;
                        paramList->append(p);
                    }
                    childNode = childNode.nextSibling();
                }
            }
            else if (nodeElement.tagName() == "Config")
            {
                QDomNode childNode = node.firstChild();
                while (!childNode.isNull())
                {
                    QDomElement child = childNode.toElement();
                    if (child.tagName() == "Byte")
                    {
                        ConfigBase *cfg = new ConfigBase();
                        QString type = "";
                        int value;
                        bool ok;

                        if (child.hasAttribute("type"))
                            type = child.attribute("type", "0");
                        if (child.hasAttribute("value"))
                            value = child.attribute("value", "0").toInt(&ok, 10);
                        cfg->value = value;
                        cfg->type = ctUnknown;
                        if (type == "const")
                            cfg->type = ctConst;
                        else if (type == "param")
                            cfg->type = ctParam;
                        else if (type == "netpin")
                            cfg->type = ctNetPin;
                        else if (type == "checksum")
                            cfg->type = ctChecksum;

                        configList->append(cfg);
                    }
                    childNode = childNode.nextSibling();
                }
/*
                bool ok;
                int w=0, h=0;
                if (nodeElement.hasAttribute("width"))
                    w = nodeElement.attribute("width", "0").toInt(&ok, 10);
                if (nodeElement.hasAttribute("height"))
                    h = nodeElement.attribute("height", "0").toInt(&ok, 10);

                qDebug() << "Size " << w << " " << h;
                this->setGeometry(1, 1, w, h);
*/
            }
            node = node.nextSibling();
        }
    }
}

